package me.keiwu.admin.service.impl;

import me.keiwu.admin.dao.WXQRCodeDao;
import me.keiwu.admin.domain.WXQRCode;
import me.keiwu.admin.service.WXQRCodeService;
import me.keiwu.pub.data.RGB;
import me.keiwu.pub.data.cos.UploadResponse;
import me.keiwu.pub.util.wx.WXQRCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created by kei on 08/12/2017.
 */
@Service
@Transactional
public class WXQRCodeServiceImpl implements WXQRCodeService{


    @Autowired
    private WXQRCodeUtil wxqrCodeUtil;
    @Autowired
    private WXQRCodeDao wxqrCodeDao;


    ReadWriteLock rwlock = new ReentrantReadWriteLock();
    private static final Logger logger = LoggerFactory.getLogger(WXQRCodeServiceImpl.class);




    @Override
    public Page<WXQRCode> listQRCode(int page, int size) {
        Sort sort = new Sort(Sort.Direction.DESC, "createdDate");
        Pageable pageable = new PageRequest(page, size, sort);
        return wxqrCodeDao.findAll(pageable);
    }

    @Override
    public WXQRCode createQRCode(Integer id, String sceneStr, String description, String page, Integer width, RGB lineColor) {
        WXQRCode code;
        if (id != null) {
            code = wxqrCodeDao.findOne(id);
        } else {
            Integer count = wxqrCodeDao.countBySceneStr(sceneStr);
            if (count != null && count > 0) {
                return null;
            }
            code = new WXQRCode();
        }
        UploadResponse resp = wxqrCodeUtil.createQRCode(sceneStr, page, width, lineColor);
        if (resp != null) {
            code.setSceneStr(sceneStr);
            code.setDescription(description);
            code.setUrl(resp.getSourceUrl());
            code.setCosPath(resp.getCosPath());
            wxqrCodeDao.save(code);
            return code;
        }
        return null;
    }


    // 加锁
    @Async
    @Override
    public void incrVisits(String sceneStr) {
        rwlock.writeLock().lock();
        try {
            WXQRCode code = wxqrCodeDao.findBySceneStr(sceneStr);
            if (code == null) return;
            code.setVisits(code.getVisits() + 1);
            wxqrCodeDao.save(code);
        } catch (Exception e) {
            logger.error("incrVisits fail! ", e);
        } finally {
            rwlock.writeLock().unlock();
        }

    }

    @Async
    @Override
    public void incrRegisters(String sceneStr) {
        rwlock.writeLock().lock();
        try {
            WXQRCode code = wxqrCodeDao.findBySceneStr(sceneStr);
            if (code == null) return;
            code.setRegisters(code.getRegisters() + 1);
            code.setVisits(code.getVisits() + 1);
            wxqrCodeDao.save(code);
        } catch (Exception e) {
            logger.error("incrRegisters fail! ", e);
        } finally {
            rwlock.writeLock().unlock();
        }
    }



    public static void main(String[] args) {
//        System.out.println(str.substring(str..indexOf("/")));
    }

}
